`include "define.v"
module MEM_WB
(
    input   wire                clk,
    input   wire                rstn,
    input   wire                flush,
    input   wire                stall,
    //
    input   wire                MEM_WB_BUBBLE_FLAG_i,
    input   wire    [31:00]     MEM_WB_INSTR_i,
    input   wire    [63:00]     MEM_WB_PC_i,
    //
    input   wire                MEM_WB_GPR_WRITE_BACK_EN_i,
    input   wire    [04:00]     MEM_WB_GPR_WRITE_BACK_ID_i,
    input   wire                MEM_WB_GPR_WRITE_BACK_FROM_ALU_i,
    input   wire                MEM_WB_GPR_WRITE_BACK_FROM_LSU_i,
    input   wire                MEM_WB_GPR_WRITE_BACK_FROM_MDU_i,
    input   wire                MEM_WB_CSR_WRITE_BACK_EN_i,
    input   wire    [11:00]     MEM_WB_CSR_WRITE_BACK_ID_i,
    // Data
    input   wire    [63:00]     MEM_WB_ALU_OUTPUT_i,
    input   wire    [63:00]     MEM_WB_LSU_OUTPUT_i,
    input   wire    [63:00]     MEM_WB_MDU_OUTPUT_i,
    input   wire    [63:00]     MEM_WB_CSR_WRITE_BACK_DATA_i,
    //
    input   wire                MEM_WB_INSTR_ADDR_MISALIG_i,
    input   wire                MEM_WB_INSTR_ACC_FAULT_i   ,
    input   wire                MEM_WB_ILLEGAL_INSTR_i     ,
    input   wire                MEM_WB_EBREAK_i            ,
    input   wire                MEM_WB_LOAD_ADDR_MISALIG_i ,
    input   wire                MEM_WB_LOAD_ACC_FAULT_i    ,
    input   wire                MEM_WB_STORE_ADDR_MISALIG_i,
    input   wire                MEM_WB_STORE_ACC_FAULT_i   ,
    input   wire                MEM_WB_ECALL_i             ,
    input   wire                MEM_WB_MRET_FLAG_i         ,
    input   wire                MEM_WB_WFI_FLAG_i          ,
    input   wire                MEM_WB_EXC_FLAG_i          ,
    input   wire                MEM_WB_MEI_i,
    input   wire                MEM_WB_MSI_i,
    input   wire                MEM_WB_MTI_i,
    
//--------------------------------------------------------
    output  reg                 MEM_WB_BUBBLE_FLAG_o, 
    output  reg     [31:00]     MEM_WB_INSTR_o,
    output  reg     [63:00]     MEM_WB_PC_o,                                                     
    //
    output  reg                 MEM_WB_GPR_WRITE_BACK_EN_o,                   
    output  reg     [04:00]     MEM_WB_GPR_WRITE_BACK_ID_o,                   
    output  reg                 MEM_WB_GPR_WRITE_BACK_FROM_ALU_o,
    output  reg                 MEM_WB_GPR_WRITE_BACK_FROM_LSU_o,
    output  reg                 MEM_WB_GPR_WRITE_BACK_FROM_MDU_o,
    output  reg                 MEM_WB_CSR_WRITE_BACK_EN_o,                   
    output  reg     [11:00]     MEM_WB_CSR_WRITE_BACK_ID_o,
    //

                                         
    // Data
    output  reg     [63:00]     MEM_WB_ALU_OUTPUT_o,
    output  reg     [63:00]     MEM_WB_LSU_OUTPUT_o,
    output  reg     [63:00]     MEM_WB_MDU_OUTPUT_o,                                    
    output  reg     [63:00]     MEM_WB_CSR_WRITE_BACK_DATA_o,
    //
    output  reg                 MEM_WB_INSTR_ADDR_MISALIG_o,
    output  reg                 MEM_WB_INSTR_ACC_FAULT_o   ,
    output  reg                 MEM_WB_ILLEGAL_INSTR_o     ,
    output  reg                 MEM_WB_EBREAK_o            ,
    output  reg                 MEM_WB_LOAD_ADDR_MISALIG_o ,
    output  reg                 MEM_WB_LOAD_ACC_FAULT_o    ,
    output  reg                 MEM_WB_STORE_ADDR_MISALIG_o,
    output  reg                 MEM_WB_STORE_ACC_FAULT_o   ,
    output  reg                 MEM_WB_ECALL_o             ,
    output  reg                 MEM_WB_MRET_FLAG_o         ,
    output  reg                 MEM_WB_WFI_FLAG_o          ,
    output  reg                 MEM_WB_EXC_FLAG_o           ,
    output  reg                 MEM_WB_MEI_o,
    output  reg                 MEM_WB_MSI_o,
    output  reg                 MEM_WB_MTI_o                  
);
    always @(posedge clk ) begin
        if (!rstn | flush) begin
            MEM_WB_BUBBLE_FLAG_o                                        <=  1'b1;        // flush后产生气泡 
            MEM_WB_INSTR_o                                              <=  `BUBBLE;
            MEM_WB_PC_o                                                 <=  64'b0;                               
            MEM_WB_GPR_WRITE_BACK_EN_o                                  <=  1'b0;      
            MEM_WB_GPR_WRITE_BACK_ID_o                                  <=  5'b0;
            MEM_WB_GPR_WRITE_BACK_FROM_ALU_o                            <=  1'b0;
            MEM_WB_GPR_WRITE_BACK_FROM_LSU_o                            <=  1'b0;
            MEM_WB_GPR_WRITE_BACK_FROM_MDU_o                            <=  1'b0;      
            MEM_WB_CSR_WRITE_BACK_EN_o                                  <=  1'b0;      
            MEM_WB_CSR_WRITE_BACK_ID_o                                  <=  12'b0;
            MEM_WB_ALU_OUTPUT_o                                         <=  64'b0;
            MEM_WB_LSU_OUTPUT_o                                         <=  64'b0;
            MEM_WB_MDU_OUTPUT_o                                         <=  64'b0;
            MEM_WB_CSR_WRITE_BACK_DATA_o                                <=  64'b0;  
            MEM_WB_INSTR_ADDR_MISALIG_o                                 <=  1'b0;
            MEM_WB_INSTR_ACC_FAULT_o                                    <=  1'b0;
            MEM_WB_ILLEGAL_INSTR_o                                      <=  1'b0;
            MEM_WB_EBREAK_o                                             <=  1'b0;
            MEM_WB_LOAD_ADDR_MISALIG_o                                  <=  1'b0;
            MEM_WB_LOAD_ACC_FAULT_o                                     <=  1'b0;
            MEM_WB_STORE_ADDR_MISALIG_o                                 <=  1'b0;
            MEM_WB_STORE_ACC_FAULT_o                                    <=  1'b0;
            MEM_WB_ECALL_o                                              <=  1'b0;
            MEM_WB_MRET_FLAG_o                                          <=  1'b0;
            MEM_WB_WFI_FLAG_o                                           <=  1'b0;
            MEM_WB_EXC_FLAG_o                                           <=  1'b0;  
            MEM_WB_MEI_o                                                <=  1'b0;
            MEM_WB_MSI_o                                                <=  1'b0;
            MEM_WB_MTI_o                                                <=  1'b0;    
        end
        else if( stall ) begin
            MEM_WB_BUBBLE_FLAG_o                                        <=  MEM_WB_BUBBLE_FLAG_o;  
            MEM_WB_INSTR_o                                              <=  MEM_WB_INSTR_o;
            MEM_WB_PC_o                                                 <=  MEM_WB_PC_o;                                        
            MEM_WB_GPR_WRITE_BACK_EN_o                                  <=  MEM_WB_GPR_WRITE_BACK_EN_o;      
            MEM_WB_GPR_WRITE_BACK_ID_o                                  <=  MEM_WB_GPR_WRITE_BACK_ID_o;
            MEM_WB_GPR_WRITE_BACK_FROM_ALU_o                            <=  MEM_WB_GPR_WRITE_BACK_FROM_ALU_o;
            MEM_WB_GPR_WRITE_BACK_FROM_LSU_o                            <=  MEM_WB_GPR_WRITE_BACK_FROM_LSU_o;
            MEM_WB_GPR_WRITE_BACK_FROM_MDU_o                            <=  MEM_WB_GPR_WRITE_BACK_FROM_MDU_o;      
            MEM_WB_CSR_WRITE_BACK_EN_o                                  <=  MEM_WB_CSR_WRITE_BACK_EN_o;      
            MEM_WB_CSR_WRITE_BACK_ID_o                                  <=  MEM_WB_CSR_WRITE_BACK_ID_o;
            MEM_WB_ALU_OUTPUT_o                                         <=  MEM_WB_ALU_OUTPUT_o;
            MEM_WB_LSU_OUTPUT_o                                         <=  MEM_WB_LSU_OUTPUT_o; 
            MEM_WB_MDU_OUTPUT_o                                         <=  MEM_WB_MDU_OUTPUT_o;                                         
            MEM_WB_CSR_WRITE_BACK_DATA_o                                <=  MEM_WB_CSR_WRITE_BACK_DATA_o;
            MEM_WB_INSTR_ADDR_MISALIG_o                                 <=  MEM_WB_INSTR_ADDR_MISALIG_o;
            MEM_WB_INSTR_ACC_FAULT_o                                    <=  MEM_WB_INSTR_ACC_FAULT_o   ;
            MEM_WB_ILLEGAL_INSTR_o                                      <=  MEM_WB_ILLEGAL_INSTR_o     ;
            MEM_WB_EBREAK_o                                             <=  MEM_WB_EBREAK_o            ;
            MEM_WB_LOAD_ADDR_MISALIG_o                                  <=  MEM_WB_LOAD_ADDR_MISALIG_o ;
            MEM_WB_LOAD_ACC_FAULT_o                                     <=  MEM_WB_LOAD_ACC_FAULT_o    ;
            MEM_WB_STORE_ADDR_MISALIG_o                                 <=  MEM_WB_STORE_ADDR_MISALIG_o;
            MEM_WB_STORE_ACC_FAULT_o                                    <=  MEM_WB_STORE_ACC_FAULT_o   ;
            MEM_WB_ECALL_o                                              <=  MEM_WB_ECALL_o             ;
            MEM_WB_MRET_FLAG_o                                          <=  MEM_WB_MRET_FLAG_o         ;
            MEM_WB_WFI_FLAG_o                                           <=  MEM_WB_WFI_FLAG_o          ;
            MEM_WB_EXC_FLAG_o                                           <=  MEM_WB_EXC_FLAG_o          ;
            MEM_WB_MEI_o                                                <=  MEM_WB_MEI_o;
            MEM_WB_MSI_o                                                <=  MEM_WB_MSI_o;
            MEM_WB_MTI_o                                                <=  MEM_WB_MTI_o;
        end
        else    begin
            MEM_WB_BUBBLE_FLAG_o                                        <=  MEM_WB_BUBBLE_FLAG_i; 
            MEM_WB_INSTR_o                                              <=  MEM_WB_INSTR_i;
            MEM_WB_PC_o                                                 <=  MEM_WB_PC_i;                                           
            MEM_WB_GPR_WRITE_BACK_EN_o                                  <=  MEM_WB_GPR_WRITE_BACK_EN_i;      
            MEM_WB_GPR_WRITE_BACK_ID_o                                  <=  MEM_WB_GPR_WRITE_BACK_ID_i;
            MEM_WB_GPR_WRITE_BACK_FROM_ALU_o                            <=  MEM_WB_GPR_WRITE_BACK_FROM_ALU_i;
            MEM_WB_GPR_WRITE_BACK_FROM_LSU_o                            <=  MEM_WB_GPR_WRITE_BACK_FROM_LSU_i;
            MEM_WB_GPR_WRITE_BACK_FROM_MDU_o                            <=  MEM_WB_GPR_WRITE_BACK_FROM_MDU_i;      
            MEM_WB_CSR_WRITE_BACK_EN_o                                  <=  MEM_WB_CSR_WRITE_BACK_EN_i;      
            MEM_WB_CSR_WRITE_BACK_ID_o                                  <=  MEM_WB_CSR_WRITE_BACK_ID_i;
            MEM_WB_ALU_OUTPUT_o                                         <=  MEM_WB_ALU_OUTPUT_i;
            MEM_WB_LSU_OUTPUT_o                                         <=  MEM_WB_LSU_OUTPUT_i;
            MEM_WB_MDU_OUTPUT_o                                         <=  MEM_WB_MDU_OUTPUT_i;                   
            MEM_WB_CSR_WRITE_BACK_DATA_o                                <=  MEM_WB_CSR_WRITE_BACK_DATA_i;
            //
            MEM_WB_INSTR_ADDR_MISALIG_o                                 <=  MEM_WB_INSTR_ADDR_MISALIG_i;
            MEM_WB_INSTR_ACC_FAULT_o                                    <=  MEM_WB_INSTR_ACC_FAULT_i   ;
            MEM_WB_ILLEGAL_INSTR_o                                      <=  MEM_WB_ILLEGAL_INSTR_i     ;
            MEM_WB_EBREAK_o                                             <=  MEM_WB_EBREAK_i            ;
            MEM_WB_LOAD_ADDR_MISALIG_o                                  <=  MEM_WB_LOAD_ADDR_MISALIG_i ;
            MEM_WB_LOAD_ACC_FAULT_o                                     <=  MEM_WB_LOAD_ACC_FAULT_i    ;
            MEM_WB_STORE_ADDR_MISALIG_o                                 <=  MEM_WB_STORE_ADDR_MISALIG_i;
            MEM_WB_STORE_ACC_FAULT_o                                    <=  MEM_WB_STORE_ACC_FAULT_i   ;
            MEM_WB_ECALL_o                                              <=  MEM_WB_ECALL_i             ;
            MEM_WB_MRET_FLAG_o                                          <=  MEM_WB_MRET_FLAG_i         ;
            MEM_WB_WFI_FLAG_o                                           <=  MEM_WB_WFI_FLAG_i          ;
            MEM_WB_EXC_FLAG_o                                           <=  MEM_WB_EXC_FLAG_i          ;
            MEM_WB_MEI_o                                                <=  MEM_WB_MEI_i;
            MEM_WB_MSI_o                                                <=  MEM_WB_MSI_i;
            MEM_WB_MTI_o                                                <=  MEM_WB_MTI_i;
        end  
    end

endmodule